package com.chat;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;

@Component
@ServerEndpoint("/chat/{token}")
@Slf4j
public class ChatServer {

    /**
     * 每个客户端一个token
     */
    //private String token = "";
    private static HashMap<String, Session> map = new HashMap<>();
    ObjectMapper objectMapper = new ObjectMapper();
    @OnOpen
    public void handleOpen(Session session, @PathParam("token") String token) {
        map.put(token, session);
        log.info("Client is now connected... {} 当前连接数：{}",session.getId(),map.size());
        log.info("token:{}",token);
    }

    @OnMessage
    public String handleMessage(String message) {
        log.info("Received from client: " + message);

        try {
            Message message1 = objectMapper.readValue(message,Message.class);
            log.info(message1.toString());
            sendInfo(message1);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
//        sendInfo(message);
        return "ok";
    }

    @OnClose
    public void handleClose(Session session) {
        log.info("Client is now disconnected... {}",session.getId());
        try {
            session.close();
            Iterator<String> iterator = map.keySet().iterator();
            while (iterator.hasNext()) {
                String token = iterator.next();
                Session s = map.get(token);
                if (!s.isOpen()) {
                    iterator.remove();
                    log.info("token:{} sid:{}  关闭连接",token,s.getId());
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    @OnError
    public void handleError(Throwable t) {
        t.printStackTrace();
    }

    /**
     * 群发消息
     */
    public void sendInfo(Message message) {

        for (String id : map.keySet()) {
            Session session = map.get(id);
            try {
                if(session.isOpen()) {
                    session.getBasicRemote().sendText(objectMapper.writeValueAsString(message));
                }
            } catch (IOException e) {
                log.error("推送消息失败：{}，内容：{}", id, message);
            }
            log.info("推送消息：{}，内容：{}", id, message);
        }
    }
}
